void _gdk_offscreen_window_new (GdkWindow *window,
GdkWindowAttr *attributes,
gint attributes_mask);
+cairo_surface_t * _gdk_offscreen_window_create_surface (GdkWindow *window,
+ gint width,
+ gint height);
/************************************
VOID:POINTER,POINTER,POINTER
OBJECT:VOID
OBJECT:DOUBLE,DOUBLE
+BOXED:INT,INT
VOID:DOUBLE,DOUBLE,POINTER,POINTER
if (! offscreen->surface)
{
GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper;
- cairo_surface_t *similar;
- similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
-
- offscreen->surface = cairo_surface_create_similar (similar,
- /* FIXME: use visual */
- CAIRO_CONTENT_COLOR,
- private->width,
- private->height);
-
- cairo_surface_destroy (similar);
+ g_signal_emit_by_name (private, "create-surface",
+ private->width,
+ private->height,
+ &offscreen->surface);
}
return offscreen->surface;
return cairo_surface_reference (get_surface (offscreen));
}
+cairo_surface_t *
+_gdk_offscreen_window_create_surface (GdkWindow *offscreen,
+ gint width,
+ gint height)
+{
+ GdkWindowObject *private = (GdkWindowObject *) offscreen;
+ cairo_surface_t *similar;
+ cairo_surface_t *surface;
+
+ g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (private->impl), NULL);
+
+ similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
+
+ surface = cairo_surface_create_similar (similar,
+ /* FIXME: use visual */
+ CAIRO_CONTENT_COLOR,
+ width,
+ height);
+
+ cairo_surface_destroy (similar);
+
+ return surface;
+}
+
void
_gdk_offscreen_window_new (GdkWindow *window,
GdkWindowAttr *attributes,
#include "config.h"
+#include <cairo-gobject.h>
+
#include "gdkwindow.h"
#ifdef GDK_WINDOWING_X11
PICK_EMBEDDED_CHILD, /* only called if children are embedded */
TO_EMBEDDER,
FROM_EMBEDDER,
+ CREATE_SURFACE,
LAST_SIGNAL
};
return g_value_get_object (handler_return) == NULL;
}
+static gboolean
+create_surface_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer data)
+{
+ g_value_copy (handler_return, return_accu);
+
+ /* Stop on the first non-NULL return value */
+ return g_value_get_boxed (handler_return) == NULL;
+}
+
static GQuark quark_pointer_window = 0;
static void
drawable_class->get_clip_region = gdk_window_get_clip_region;
drawable_class->get_visible_region = gdk_window_get_visible_region;
+ klass->create_surface = _gdk_offscreen_window_create_surface;
+
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
G_TYPE_DOUBLE,
G_TYPE_POINTER,
G_TYPE_POINTER);
+
+ /**
+ * GdkWindow::create-surface:
+ * @window: the offscreen window on which the signal is emitted
+ * @width: the width of the offscreen surface to create
+ * @height: the height of the offscreen surface to create
+ *
+ * The ::create-surface signal is emitted when an offscreen window
+ * needs its surface (re)created, which happens either when the the
+ * window is first drawn to, or when the window is being
+ * resized. The first signal handler that returns a non-%NULL
+ * surface will stop any further signal emission, and its surface
+ * will be used.
+ *
+ * Note that it is not possible to access the window's previous
+ * surface from within any callback of this signal. Calling
+ * gdk_offscreen_window_get_surface() will lead to a crash.
+ *
+ * Returns: the newly created #cairo_surface_t for the offscreen window
+ *
+ * Since: 3.0
+ */
+ signals[CREATE_SURFACE] =
+ g_signal_new (g_intern_static_string ("create-surface"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdkWindowObjectClass, create_surface),
+ create_surface_accumulator, NULL,
+ _gdk_marshal_BOXED__INT_INT,
+ CAIRO_GOBJECT_TYPE_SURFACE,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
}
static void
struct _GdkWindowObjectClass
{
GdkDrawableClass parent_class;
+
+ cairo_surface_t * (* create_surface) (GdkWindow *window,
+ gint width,
+ gint height);
};
/* Windows
offscreen_x, offscreen_y);
}
+static cairo_surface_t *
+gdk_offscreen_box_create_alpha_image_surface (GdkWindow *offscreen,
+ gint width,
+ gint height)
+{
+ return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+}
+
static void
gtk_offscreen_box_realize (GtkWidget *widget)
{
gtk_widget_set_parent_window (offscreen_box->child2, offscreen_box->offscreen_window2);
gdk_offscreen_window_set_embedder (offscreen_box->offscreen_window2,
window);
+
+ g_signal_connect (offscreen_box->offscreen_window2, "create-surface",
+ G_CALLBACK (gdk_offscreen_box_create_alpha_image_surface),
+ offscreen_box);
g_signal_connect (offscreen_box->offscreen_window2, "to-embedder",
G_CALLBACK (offscreen_window_to_parent2), offscreen_box);
g_signal_connect (offscreen_box->offscreen_window2, "from-embedder",